#include "myapp.h"
#include "mywebframe.h"
#include <XUtil/XXml.hpp>

#ifdef CEF_ON
#include <webview_chromium.h>
#endif

///
wxBEGIN_EVENT_TABLE(MyWebFrame, Base)
//EVT_ACTIVATE(MyWebFrame::OnActivateEvent)
EVT_CLOSE(MyWebFrame::OnCloseEvent)
//EVT_IDLE(MyWebFrame::OnIdle)
wxEND_EVENT_TABLE()

MyWebFrame::MyWebFrame(const char* xml, size_t xmlflag, wxWindow* parent)
	: Base(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(1024, 600)
#ifdef USE_WEB_DLG
		, wxDEFAULT_DIALOG_STYLE | wxMAXIMIZE_BOX | wxRESIZE_BORDER
#endif
	)
{
	SetIcon(wxICON(mytrader));

	CFG_FROM_XML(cfg, xml, xmlflag);
	auto url = utf2wxString(cfg.get<std::string>("url", "").c_str());
	
#ifdef CEF_ON
	m_browser = wxWebView::New(this, wxID_ANY, url, wxDefaultPosition, wxSize(1024, 600), wxWebViewBackendChromium);
#else
	m_browser = wxWebView::New(this, wxID_ANY, url, wxDefaultPosition, wxSize(1024, 600));
#endif//

	//SetDefaultItem(m_browser);

	//We register the wxfs:// protocol for testing purposes
	//m_browser->RegisterHandler(wxSharedPtr<wxWebViewHandler>(new wxWebViewArchiveHandler("wxfs")));
	//And the memory: file system
	//m_browser->RegisterHandler(wxSharedPtr<wxWebViewHandler>(new wxWebViewFSHandler("memory")));

	// Connect the webview events
	Connect(m_browser->GetId(), wxEVT_COMMAND_WEBVIEW_NAVIGATING,
		wxWebViewEventHandler(MyWebFrame::OnNavigationRequest), NULL, this);
	Connect(m_browser->GetId(), wxEVT_COMMAND_WEBVIEW_NAVIGATED,
		wxWebViewEventHandler(MyWebFrame::OnNavigationComplete), NULL, this);
	Connect(m_browser->GetId(), wxEVT_COMMAND_WEBVIEW_LOADED,
		wxWebViewEventHandler(MyWebFrame::OnDocumentLoaded), NULL, this);
	Connect(m_browser->GetId(), wxEVT_COMMAND_WEBVIEW_NEWWINDOW,
		wxWebViewEventHandler(MyWebFrame::OnNewWindow), NULL, this);
	Connect(m_browser->GetId(), wxEVT_COMMAND_WEBVIEW_TITLE_CHANGED,
		wxWebViewEventHandler(MyWebFrame::OnTitleChanged), NULL, this);
	Connect(m_browser->GetId(), wxEVT_COMMAND_WEBVIEW_ERROR,
		wxWebViewEventHandler(MyWebFrame::OnError), NULL, this);

}

MyWebFrame::~MyWebFrame()
{
	wxGetApp().ResetWebFrame(this);
}

int MyWebFrame::FilterEvent(wxEvent& event)
{
	// Continue processing the event normally as well.
	return wxEventFilter::Event_Skip;
}

void MyWebFrame::LoadURL(const wxString& url)
{
	m_browser->LoadURL(url);
}

wxString MyWebFrame::GetURL()
{
	return m_browser->GetCurrentURL();
}

void MyWebFrame::OnSkinInfoChanged()
{
	Freeze();
	//
	Layout();
	Thaw();
}

void MyWebFrame::OnActivateEvent(wxActivateEvent& event)
{
	m_browser->SetFocus();
}

void MyWebFrame::OnCloseEvent(wxCloseEvent& event)
{
#ifdef USE_WEB_DLG
	if (!IsModal()) {
		Destroy();
		return;
	}
#endif
	event.Skip();
}

/**
* Callback invoked when there is a request to load a new page (for instance
* when the user clicks a link)
*/
void MyWebFrame::OnNavigationRequest(wxWebViewEvent& evt)
{
	/*if (m_info->IsShown())
	{
		m_info->Dismiss();
	}*/

	wxLogMessage("%s", "Navigation request to '" + evt.GetURL() + "' (target='" +
		evt.GetTarget() + "')");

	wxASSERT(m_browser->IsBusy());

	////If we don't want to handle navigation then veto the event and navigation
	////will not take place, we also need to stop the loading animation
	//if (!m_tools_handle_navigation->IsChecked())
	//{
	//	evt.Veto();
	//	m_toolbar->EnableTool(m_toolbar_stop->GetId(), false);
	//}
	//else
	//{
	//	UpdateState();
	//}
}

/**
* Callback invoked when a navigation request was accepted
*/
void MyWebFrame::OnNavigationComplete(wxWebViewEvent& evt)
{
	wxLogMessage("%s", "Navigation complete; url='" + evt.GetURL() + "'");
	//UpdateState();
}

/**
* Callback invoked when a page is finished loading
*/
void MyWebFrame::OnDocumentLoaded(wxWebViewEvent& evt)
{
	//Only notify if the document is the main frame, not a subframe
	if (evt.GetURL() == m_browser->GetCurrentURL())
	{
		wxLogMessage("%s", "Document loaded; url='" + evt.GetURL() + "'");
	}
	//UpdateState();
}

/**
* On new window, we veto to stop extra windows appearing
*/
void MyWebFrame::OnNewWindow(wxWebViewEvent& evt)
{
	wxLogMessage("%s", "New window; url='" + evt.GetURL() + "'");

	//If we handle new window events then just load them in this window as we
	//are a single window browser
	//if (m_tools_handle_new_window->IsChecked())
		m_browser->LoadURL(evt.GetURL());

	//UpdateState();
}

void MyWebFrame::OnTitleChanged(wxWebViewEvent& evt)
{
	SetTitle(evt.GetString());
	wxLogMessage("%s", "Title changed; title='" + evt.GetString() + "'");
}

/**
* Callback invoked when a loading error occurs
*/
void MyWebFrame::OnError(wxWebViewEvent& evt)
{
#define WX_ERROR_CASE(type) \
    case type: \
        category = #type; \
        break;

	wxString category;
	switch (evt.GetInt())
	{
		WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_CONNECTION);
		WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_CERTIFICATE);
		WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_AUTH);
		WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_SECURITY);
		WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_NOT_FOUND);
		WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_REQUEST);
		WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_USER_CANCELLED);
		WX_ERROR_CASE(wxWEBVIEW_NAV_ERR_OTHER);
	}

	wxLogMessage("%s", "Error; url='" + evt.GetURL() + "', error='" + category + " (" + evt.GetString() + ")'");

	////Show the info bar with an error
	//m_info->ShowMessage(_("An error occurred loading ") + evt.GetURL() + "\n" +
	//	"'" + category + "'", wxICON_ERROR);

	//UpdateState();
}
